//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __CSERVICECENTRAL_H__
#define __CSERVICECENTRAL_H__

#include <elasys_server.h>
#include <linknode.h>
#include <interlocked.h>
#include <aura.h>

typedef struct ImportService : DLinkNode {
    ProcessId       m_processId;
    oid_t             m_oid;
    //pContext     m_pContext;
}ImportService;

class ServiceWaiter: public DLinkNode
{
public:
    ServiceWaiter(WString name);
    ~ServiceWaiter();

    ECode Initialize();

    ECode TryWait(
        /* [in]  */ Millisecond32 msTimeOut,
        /* [out] */ WaitResult * pResult);
    ECode Notify();

public:
    WString m_waiterName;

private:
    PVoid   m_hNotifyEvent;
};

INLINE ServiceWaiter:: ServiceWaiter(
        /* [in] */ WString name)
        : m_waiterName(name),
          m_hNotifyEvent(NULL) {}

class CServiceCentral
{
public:
    CARAPI Register(
        /* [in]  */ ProcessId processId,
        /* [in]  */ PEMuid pClsid,
        /* [in]  */ PEIID   pIid,
        /* [in]  */ UInt32 uIndex,
        /* [out] */ oid_t * pOid);

    CARAPI Unregister(
        /* [in]  */ ProcessId processId,
        /* [in]  */ oid_t oid);

    CARAPI RegisterCommon(
        /* [in]  */ WString name,
        /* [in]  */ ProcessId processId,
        /* [in]  */ PEMuid pClsid,
        /* [in]  */ PEIID   pIid,
        /* [in]  */ UInt32 uIndex,
        /* [out] */ oid_t * pOid);

    CARAPI CreateNamedObject(
        /* [in]  */ WString name,
        /* [in]  */ ProcessId processId,
        /* [in]  */ ObjectType type,
        /* [out] */ Boolean * pbAlreayExisted,
        /* [out] */ oid_t * pOid);

    CARAPI DeleteNamedObject(
        /* [in]  */ oid_t oid);

    CARAPI UnregisterCommon(
        /* [in]  */ WString name,
        /* [in]  */ ProcessId processId);

    CARAPI ResolveCommon(
        /* [in]  */ WString name,
        /* [out] */ ProcessId * pProcessId,
        /* [out] */ ObjectType * pType,
        /* [out] */ oid_t * pOid,
        /* [out] */ EMuid * pClsId,
        /* [out] */ UInt32 * pUIndex);

    CARAPI GetProcessIdByServiceOid(
        /* [in]  */ oid_t oid,
        /* [out] */ ProcessId * pProcessId);

    CARAPI RegisterService(
        /* [in]  */ WString name,
        /* [in]  */ ProcessId processId,
        /* [in]  */ oid_t oid);

    CARAPI WaitService(
        /* [in]  */ WString serviceName,
        /* [in]  */ Millisecond32 msTimeout,
        /* [out] */ WaitResult * pResult);

    CARAPI AttachImportService(
        /* [in] */ ProcessId processId,
        /* [in] */ oid_t oid);

    CARAPI DetachImportService(
        /* [in] */ ProcessId processId,
        /* [in] */ oid_t oid);

    CARAPI UnregisterAll(
        /* [in] */ ProcessId processId);

public:
    CServiceCentral();
    ~CServiceCentral();
    ECode Initialize();

private:
    void NotifyServiceWaiters(WString name);

private:
    PVoid m_hServiceLock;

    DLinkNode m_srvWaitersList;
    PVoid m_hSrvWaitersListLock;

private:
    Interlocked m_refs;
};

#endif // __CSYSCALLCENTRAL_H__
